package com.huawei.app.httpapi;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.huawei.app.demo.util.LogUtils;

/**
 * HTTP API接口工具类
 */
public class IdeaHubHttpApiUtils {

    private static final String TAG = IdeaHubHttpApiUtils.class.getSimpleName();

    private static IdeaHubHttpApiUtils instance = new IdeaHubHttpApiUtils();
    private String baseUrl = "https://127.0.0.1";
    private String token;
    private HeartbeatTask heartbeatTask;
    private boolean loginSuccess = false;

    public static IdeaHubHttpApiUtils getInstance() {
        return instance;
    }

    public boolean isLoginSuccess() {
        return loginSuccess;
    }

    public HttpApiResult login(String ip, String user, String pass) {
        this.baseUrl = "https://" + ip;

        HttpApiResult apiResult = initSessionId();
        if (!apiResult.isSuccess()) {
            LogUtils.getInstance().e(TAG, "init sessionId failed.");
            return apiResult;

        }

        apiResult = login(user, pass);
        if (!apiResult.isSuccess()) {
            LogUtils.getInstance().e(TAG, "login failed, result is " + apiResult);
            return apiResult;
        }

        apiResult = changeSeesionId();
        if (!apiResult.isSuccess()) {
            LogUtils.getInstance().e(TAG, "change sessionId failed, result is " + apiResult);
            return apiResult;
        }

        loginSuccess = true;
        return HttpApiResult.success();
    }

    /**
     * 请求SessionID
     *
     * @return 返回sessionid
     */
    private HttpApiResult initSessionId() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_RequestSessionIDAPI";
        Map<String, String> header = new HashMap<>();
        HttpClientUtil.post(uri, null, header);

        if (TextUtils.isEmpty(HttpClientUtil.sessionId)) {
            return HttpApiResult.failed(HttpApiResult.HTTP_ERROR_CODE, "init sessionId failed.");
        }
        return HttpApiResult.success();
    }

    /**
     * 登录Login
     * @param user
     * @param pass
     * @return
     */
    private HttpApiResult login(String user, String pass) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_RequestCertificateAPI";

        JSONObject bodyJsonObj = new JSONObject();
        bodyJsonObj.put("user", user);
        bodyJsonObj.put("password", pass);

        JSONObject result = HttpClientUtil.post(uri, bodyJsonObj, null);
        if (result == null) {
            return HttpApiResult.failed(HttpApiResult.HTTP_ERROR_CODE, "send WEB_RequestCertificateAPI failed, result is null.");
        }

        HttpApiResult apiResult = new HttpApiResult();
        try {
            int success = result.getIntValue("success");
            apiResult.setRetCode(success);

            if (success == 1) {
                JSONObject dataObj = result.getJSONObject("data");
                this.token = dataObj.getString("acCSRFToken");
                apiResult.setData(this.token);
            } else {
                String error = result.getJSONObject("error").toString();
                apiResult.setErrorMsg(error);
            }
        } catch (Exception e) {
            LogUtils.getInstance().e(TAG, "send WEB_RequestCertificateAPI failed, " + e.getMessage());
            apiResult.setRetCode(HttpApiResult.UKNOW_ERROR_CODE);
            apiResult.setErrorMsg(e.getMessage());
        }
        return apiResult;
    }

    /**
     * 更换SessionID
     * @return
     */
    private HttpApiResult changeSeesionId() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_ChangeSessionIDAPI";

        String oldSessionId = HttpClientUtil.sessionId;
        HttpClientUtil.post(uri, null, null);
        if (oldSessionId != null && !oldSessionId.equals(HttpClientUtil.sessionId)) {
            return HttpApiResult.success();
        }
        return HttpApiResult.failed(HttpApiResult.HTTP_ERROR_CODE, "change sessionId failed.");
    }

    /**
     * 启动心跳
     */
    public void startHeartbeat() {
        if (heartbeatTask != null) {
            heartbeatTask.setRunning(false);
        }
        heartbeatTask = new HeartbeatTask();
        ThreadPools.schedule(heartbeatTask, 20000, TimeUnit.MILLISECONDS);
    }

    /**
     * 注册消息处理类
     * @param msgCallback
     */
    public void registerMsgCall(MsgRspCallback msgCallback) {
        if (this.heartbeatTask == null || msgCallback == null) {
            return;
        }
        this.heartbeatTask.registerMsgCall(msgCallback);
    }

    /**
     * 删除消息处理类
     * @param msgCallback
     */
    public void unregisterMsgCall(MsgRspCallback msgCallback) {
        if (this.heartbeatTask == null || msgCallback == null) {
            return;
        }
        this.heartbeatTask.unregisterMsgCall(msgCallback.getMsgId(), msgCallback.getMsgName());
    }

    /**
     * 获取终端型号model/版本信息softVersion/终端序列号lisence
     */
    public HttpApiResult getVersionInfo() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetVersionInfoAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetVersionInfoAPI", result);
    }

    /**
     * 查询配置项当前值
     * @return
     */
    public HttpApiResult getParamValues(String[] paramNames) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetCfgParamAPI";
        if (paramNames == null || paramNames.length == 0) {
            return HttpApiResult.success();
        }

        JSONArray cfgIdArray = new JSONArray();
        for (String paramName : paramNames) {
            cfgIdArray.add(paramName);
        }

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("CfgIDString", cfgIdArray);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetCfgParamAPI", result);
    }

    /**
     * 隐藏WiFi图标, 投屏码
     * @return
     */
    public HttpApiResult hideIcon() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SaveCfgParamAPI";

        JSONObject item10 = new JSONObject();
        item10.put("CfgItemID", "iconWifi");
        item10.put("CfgItemInfo", 0);

        JSONObject item11 = new JSONObject();
        item11.put("CfgItemID", "iconLostpacket");
        item11.put("CfgItemInfo", 0);

        JSONObject item12 = new JSONObject();
        item12.put("CfgItemID", "airShareMode");
        item12.put("CfgItemInfo", 0);

        JSONObject item13 = new JSONObject();
        item13.put("CfgItemID", "airCodeDisplay");
        item13.put("CfgItemInfo", 0);

        JSONArray itemIntArray = new JSONArray();
        itemIntArray.add(item10);
        itemIntArray.add(item11);
        itemIntArray.add(item12);
        itemIntArray.add(item13);

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("CfgItemInt", itemIntArray);
        obj.put("CfgItemString",new JSONArray());

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SaveCfgParamAPI", result);
    }

    /**
     * 显示WiFi图标, 投屏码
     * @return
     */
    public HttpApiResult showIcon() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SaveCfgParamAPI";

        JSONObject item10 = new JSONObject();
        item10.put("CfgItemID", "iconWifi");
        item10.put("CfgItemInfo", 1);

        JSONObject item11 = new JSONObject();
        item11.put("CfgItemID", "iconLostpacket");
        item11.put("CfgItemInfo", 1);

        JSONObject item12 = new JSONObject();
        item12.put("CfgItemID", "airShareMode");
        item12.put("CfgItemInfo", 0);

        JSONObject item13 = new JSONObject();
        item13.put("CfgItemID", "airCodeDisplay");
        item13.put("CfgItemInfo", 1);

        JSONArray itemIntArray = new JSONArray();
        itemIntArray.add(item10);
        itemIntArray.add(item11);
        itemIntArray.add(item12);
        itemIntArray.add(item13);

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("CfgItemInt", itemIntArray);
        obj.put("CfgItemString",new JSONArray());

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SaveCfgParamAPI", result);
    }

    /**
     * 修改api鉴权密码
     * @param oldApiPass
     * @param newApiPass
     * @return
     */
    public HttpApiResult modifyApiPass(String oldApiPass, String newApiPass) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SaveCfgParamAPI";

        JSONObject item1 = new JSONObject();
        item1.put("CfgItemID", "api_user");
        item1.put("CfgItemInfo", "api");

        JSONObject item2 = new JSONObject();
        item2.put("CfgItemID", "api_pass_old");
        item2.put("CfgItemInfo", oldApiPass);

        JSONObject item3 = new JSONObject();
        item3.put("CfgItemID", "api_pass");
        item3.put("CfgItemInfo", newApiPass);

        JSONArray itemStrArray = new JSONArray();
        itemStrArray.add(item1);
        itemStrArray.add(item2);
        itemStrArray.add(item3);

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("CfgItemInt", new JSONArray());
        obj.put("CfgItemString", itemStrArray);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SaveCfgParamAPI", result);
    }

    /**
     * 查询终端连接的外设序列号
     */
    public HttpApiResult getEquipmentSn() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetEquipmentSn";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetEquipmentSn", result);
    }

    /**
     * 重启
     */
    public HttpApiResult reboot() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_RequestRebootAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_RequestRebootAPI", result);
    }

    /**
     * 关机
     */
    public HttpApiResult powerDown() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_RequestPowerDownAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_RequestPowerDownAPI", result);
    }

    /**
     * 休眠
     */
    public HttpApiResult startSleep() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_StartTermSleepAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_StartTermSleepAPI", result);
    }

    /**
     * 唤醒
     */
    public HttpApiResult wakeUp() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SystemWakeUpAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SystemWakeUpAPI", result);
    }

    /**
     * 查询休眠状态
     * @return
     */
    public HttpApiResult getSleepStatus() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_IsSystemSleepAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_IsSystemSleepAPI", result);
    }

    /**
     * 静默安装/升级三方APP
     */
    public HttpApiResult installApk(String apkPath, String componentName) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_RequestInstallApkAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("apkPath", apkPath);
        obj.put("componentName", componentName);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_RequestInstallApkAPI", result);
    }

    /**
     * 设置霸屏应用
     */
    public HttpApiResult setTopAppPkg(String pkgName) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SetSingleAppAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("packageName", pkgName);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SetSingleAppAPI", result);
    }

    /**
     * 查询霸屏应用
     */
    public HttpApiResult getTopAppPkg() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetSingleAppAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetSingleAppAPI", result);
    }

    /**
     * 设置投屏窗口位置和大小
     */
    public HttpApiResult setCastWindowLayout(int top, int left, int width, int height) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SetCastWindowLayoutAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("shareType", 5);
        // 1920x1080 -> 3840x2160
        obj.put("top", top*2);
        obj.put("left", left*2);
        obj.put("width", width*2);
        obj.put("height", height*2);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SetCastWindowLayoutAPI", result);
    }

    /**
     * 创建会议
     * @param confId
     * @param confPwd
     * @param type
     * @return
     */
    public HttpApiResult createConf(String confId, String confPwd, int type) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_CallNumberWithPwdAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("number", confId);
        obj.put("passwd", confPwd);
        obj.put("mediaTypes", type);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_CallNumberWithPwdAPI", result);
    }

    /**
     * 获取本地会场信息
     * @return
     */
    public HttpApiResult getLocalConfInfo() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetCloudTypeList";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetCloudTypeList", result);
    }

    /**
     * 查询通讯录
     * @return
     */
    public HttpApiResult searchLdapAddr() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SeachLdapAddrAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("szKeyWords", "");

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SeachLdapAddrAPI", result);
    }

    /**
     * 获取通讯录查询结果
     * @return
     */
    public HttpApiResult getLdapAddrResult() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetLdapAddrResultListAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetLdapAddrResultListAPI", result);
    }

    /**
     * 点对点呼叫
     * @param number 待呼叫的号码
     * @return
     */
    public HttpApiResult callNumber(String number) {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_CallNumberAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("szNumber", number);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_CallNumberAPI", result);
    }

    /**
     * 开始人脸检测
     * @return
     */
    public HttpApiResult startFaceDetection() {
        String uri = baseUrl + "/v1/ai/face-detection/start";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("face-detection/start", result);
    }

    /**
     * 停止人脸检测
     * @return
     */
    public HttpApiResult stopFaceDetection() {
        String uri = baseUrl + "/v1/ai/face-detection/stop";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("face-detection/stop", result);
    }

    /**
     * 获取人脸检测图像
     * @return
     */
    public HttpApiResult getFaceDetectionImg(int id) {
        String uri = baseUrl + "/v1/ai/face-detection/picture?id=" + id;

        Map<String,String> headers = new HashMap<>();
        headers.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.get(uri, headers);
        return convertResult("face-detection/picture", result);
    }

    /**
     * 订阅邮箱消息数据
     * @return
     */
    public HttpApiResult subscribeMsg() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_SubscribeMsgAPI";

        JSONArray msgIds = new JSONArray();
        msgIds.add("MSG_END_CONF_RSP");
        msgIds.add("MSG_AI_FACE_DETECTION_RESULT");

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);
        obj.put("aszMsgIDs", msgIds);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_SubscribeMsgAPI", result);
    }

    /**
     * 请求消息数据
     * @return
     */
    public HttpApiResult getMailboxData() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_GetMailboxDataAPI";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_GetMailboxDataAPI", result);
    }

    /**
     * 登出
     */
    private HttpApiResult logout() {
        String uri = baseUrl + "/action.cgi?ActionID=WEB_Logout";

        JSONObject obj = new JSONObject();
        obj.put("acCSRFToken", token);

        JSONObject result = HttpClientUtil.post(uri, obj, null);
        return convertResult("WEB_Logout", result);
    }

    /**
     * 转换响应消息
     * @param action
     * @param result
     * @return
     */
    private HttpApiResult convertResult(String action, JSONObject result) {
        if (result == null) {
            return HttpApiResult.failed(HttpApiResult.HTTP_ERROR_CODE, "send " + action + " failed, result is null.");
        }

        HttpApiResult apiResult = new HttpApiResult();
        try {
            int success = result.getIntValue("success");
            apiResult.setRetCode(success);

            if (success == 1) {
                Object dataObj = result.get("data");
                apiResult.setData(dataObj);
            } else {
                Object errorObj = result.get("error");
                apiResult.setErrorMsg(errorObj != null ? errorObj.toString() : "");
            }
        } catch (Exception e) {
            LogUtils.getInstance().e(TAG, "send " + action + " failed, " + e.getMessage());
            apiResult.setRetCode(HttpApiResult.UKNOW_ERROR_CODE);
            apiResult.setErrorMsg(e.getMessage());
        }
        return apiResult;
    }

    /**
     * 格式化json对象
     * @param jsonObj
     * @return
     */
    public static String toPrettyString(JSONObject jsonObj) {
        if (jsonObj == null) {
            return "";
        }
        JSONObject resultObj = new JSONObject();
        Set<String> keys = jsonObj.keySet();
        for (String key : keys) {
            Object value = jsonObj.get(key);
            if (value != null && value.toString().startsWith("{")) {
                value = JSONObject.parseObject(value.toString());
            }
            resultObj.put(key, value);
        }
        String resultStr = JSON.toJSONString(resultObj,
                SerializerFeature.PrettyFormat,
                SerializerFeature.WriteMapNullValue,
                SerializerFeature.WriteDateUseDateFormat);
        return resultStr;
    }

    private void pause(long time) {
        try {
            Thread.sleep(time);
        } catch (InterruptedException e) {
            //
        }
    }
}